#!/usr/bin/env python3
"""
增强版数字人视频背景替换API服务 - 重构版本
"""

import os
import sys
from datetime import datetime
from flask import Flask, send_from_directory
from flask_cors import CORS

from utils import app_logger
from utils.logger import configure_logging, error_logger

# 添加当前目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

# 导入配置和模块
from config import config, Config
from database import Database, UploadDAO, TaskDAO, PreviewDAO, PresetDAO
from file_manager import FileManager, PreviewManager
from task_manager import TaskManager


def create_app(config_name=None):
    """应用工厂函数"""

    # 确定配置
    if config_name is None:
        config_name = os.environ.get('FLASK_ENV', 'production')

    # 配置日志系统
    configure_logging(
        log_dir=Config.LOG_DIR,
        max_bytes=Config.LOG_MAX_BYTES,
        backup_count=Config.LOG_BACKUP_COUNT
    )

    # 创建Flask应用 - 重要：设置正确的静态文件路径
    config_class = config[config_name]

    app = Flask(__name__,
                static_folder=config_class.STATIC_FOLDER,
                template_folder=getattr(config_class, 'TEMPLATE_FOLDER', config_class.STATIC_FOLDER))

    app.config.from_object(config_class)

    # 设置CORS
    CORS(app)

    # 初始化配置
    app.config['CONFIG_CLASS'] = config_class
    config_class.init_folders()
    config_class.setup_logging()

    # 初始化数据库
    database = Database(app.config['CONFIG_CLASS'].DATABASE_FILE)
    database.init_database()

    # 初始化DAO层
    upload_dao = UploadDAO(database)
    task_dao = TaskDAO(database)
    preview_dao = PreviewDAO(database)
    preset_dao = PresetDAO(database)

    # 初始化服务层
    file_manager = FileManager()
    preview_manager = PreviewManager()
    task_manager = TaskManager(task_dao)

    # 注册API路由
    from api import create_api_blueprint
    api_blueprint = create_api_blueprint(
        upload_dao=upload_dao,
        task_dao=task_dao,
        preview_dao=preview_dao,
        preset_dao=preset_dao,
        task_manager=task_manager,
        file_manager=file_manager,
        preview_manager=preview_manager
    )
    app.register_blueprint(api_blueprint)

    @app.teardown_appcontext
    def cleanup_app(error):
        """应用上下文清理"""
        if error:
            error_logger.error(f"应用错误: {error}")

    # 存储服务实例到应用上下文
    app.upload_dao = upload_dao
    app.task_dao = task_dao
    app.preview_dao = preview_dao
    app.preset_dao = preset_dao
    app.file_manager = file_manager
    app.preview_manager = preview_manager
    app.task_manager = task_manager

    # 生产环境前端路由
    @app.route('/')
    def index():
        """前端主页"""
        try:
            return app.send_static_file('index.html')
        except Exception as e:
            app_logger.error(f"无法加载前端页面: {e}")
            return f"""
            <html>
            <head><title>数字人视频背景替换系统</title></head>
            <body>
                <h1>数字人视频背景替换系统</h1>
                <p>前端页面加载失败</p>
                <p>错误: {e}</p>
                <p>API服务正常运行，访问 <a href="/api/health">/api/health</a> 检查状态</p>
            </body>
            </html>
            """, 500

    @app.route('/assets/<path:filename>')
    def serve_assets(filename):
        """提供静态资源文件"""
        try:
            assets_dir = os.path.join(app.static_folder, 'assets')
            return send_from_directory(assets_dir, filename)
        except Exception as e:
            app_logger.error(f"无法加载静态资源 {filename}: {e}")
            return {'error': 'File not found'}, 404

    @app.route('/<path:path>')
    def catch_all(path):
        """捕获所有前端路由"""
        # 检查是否是API请求
        if path.startswith('api/'):
            return {'error': 'API endpoint not found'}, 404

        # 检查是否是静态资源
        try:
            return app.send_static_file(path)
        except:
            # 对于前端路由，返回index.html
            try:
                return app.send_static_file('index.html')
            except Exception as e:
                return f"""
                <html>
                <head><title>页面未找到</title></head>
                <body>
                    <h1>页面未找到</h1>
                    <p>请求的路径: {path}</p>
                    <p>静态文件目录: {app.static_folder}</p>
                    <p>错误: {e}</p>
                </body>
                </html>
                """, 404

    return app


def setup_periodic_cleanup(app):
    """设置定期清理任务"""
    import threading
    import time
    from file_manager import CleanupManager

    def cleanup_task():
        """定期清理任务"""
        while True:
            try:
                with app.app_context():
                    # 每小时清理一次预览文件
                    app.preview_manager.cleanup_old_previews()

                    # 每天清理一次临时文件
                    CleanupManager.cleanup_temp_files()

                    # 清理内存中的已完成任务
                    app.task_manager.cleanup_completed_tasks()

                    app_logger.info("定期清理任务完成")
            except Exception as e:
                error_logger.error(f"定期清理任务失败: {e}")

            # 等待1小时
            time.sleep(3600)

    # 启动清理线程
    cleanup_thread = threading.Thread(target=cleanup_task, daemon=True)
    cleanup_thread.start()
    app_logger.info("定期清理任务已启动")


def check_dependencies():
    """检查依赖项"""
    from video_processor import VideoBackgroundReplacer

    print("🔧 检查系统依赖...")

    # 检查ffmpeg
    replacer = VideoBackgroundReplacer('check')
    if not replacer.check_ffmpeg():
        print("⚠️  警告: ffmpeg未安装或不可用")
        print("   请安装ffmpeg以使用视频处理功能")
        return False
    else:
        print("✅ ffmpeg 可用")

    if not replacer.check_ffprobe():
        print("⚠️  警告: ffprobe未安装或不可用")
        return False
    else:
        print("✅ ffprobe 可用")

    # 检查PIL
    try:
        from PIL import Image
        print("✅ PIL/Pillow 可用")
    except ImportError:
        print("❌ PIL/Pillow 未安装")
        return False

    print("✅ 所有依赖项检查通过")
    return True


def main():
    """主函数"""
    # 检查依赖
    if not check_dependencies():
        print("❌ 依赖检查失败，请安装缺失的依赖项")
        sys.exit(1)

    # 获取配置名称
    config_name = os.environ.get('FLASK_ENV', 'production')

    # 创建应用
    app = create_app(config_name)

    # 打印配置信息（用于调试）
    print(f"📁 当前工作目录: {os.getcwd()}")
    print(f"📁 应用基础目录: {app.config['CONFIG_CLASS'].BASE_DIR}")
    print(f"📁 静态文件目录: {app.static_folder}")
    print(f"📁 上传目录: {app.config['CONFIG_CLASS'].UPLOAD_FOLDER}")

    # 检查关键目录
    if not os.path.exists(app.static_folder):
        print(f"⚠️  警告: 静态文件目录不存在: {app.static_folder}")
    else:
        print(f"✅ 静态文件目录存在")

    # 设置定期清理
    setup_periodic_cleanup(app)

    # 获取运行参数
    host = os.environ.get('HOST', '0.0.0.0')
    port = int(os.environ.get('PORT', 5001))
    debug = config_name == 'development'

    print(f"\n🌐 服务启动在 http://{host}:{port}")

    if debug:
        print("⚠️  开发模式：调试已启用")

    print("按 Ctrl+C 停止服务")
    print("="*60 + "\n")

    try:
        # 启动应用
        app.run(
            host=host,
            port=port,
            debug=debug,
            threaded=True,
            use_reloader=False  # 避免重复启动清理任务
        )
    except KeyboardInterrupt:
        print("\n👋 服务已停止")
    except Exception as e:
        print(f"\n❌ 服务启动失败: {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()